using System;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay.Editors
{
    public static class TableExportMenu
    {
        // ctrlE导出配置后的委托，用来处理编辑器中和导出配置表绑定的自动化操作
        public static Action onExportExcel;
        
        [MenuItem("GameEditor/Config/导配置表 %e")]
        private static void MenuExportExcelAll()
        {
            ExportExcelAll();
            onExportExcel?.Invoke();
        }

        [MenuItem("GameEditor/Config/导配置表(不检查错误,仅本地测试) %&e")]
        private static void MenuExportExcelAllNoCheck()
        {
            ExportExcelAll("-c");
        }

        [MenuItem("GameEditor/Config/导剧情配置 %q")]
        private static void MenuExportStoryAll()
        {
            ExportStoryAll();
        }

#if UNITY_EDITOR_OSX
        const string ToolCmdName = "table-builder-mac";
#else
        const string ToolCmdName = "table-builder.exe";
#endif

        public static readonly Regex RegexErrorSign = new Regex(@"\[\d\d:\d\d:\d\d ERR\]|\[\d\d:\d\d:\d\d FTL\]");

        public static string GetTableToolsPath(string fileName)
        {
            return Path.GetFullPath(Path.Combine(Application.dataPath, "..", "Tables", "Tools", fileName));
        }

        public static bool ExportExcelAll(string arg = "")
        {
            string toolNameFullPath = GetTableToolsPath(ToolCmdName);
            if (!ChmodAddExecute(toolNameFullPath) || !XattrExecute(toolNameFullPath))
            {
                return false;
            }
            if (!ExportExcelInternal(ToolCmdName, arg))
            {
                return false;
            }
            AssetDatabase.Refresh();
            return true;
        }

        public static bool ExportStoryAll()
        {
            string toolNameFullPath = GetTableToolsPath(ToolCmdName);
            if (!ChmodAddExecute(toolNameFullPath) || !XattrExecute(toolNameFullPath))
            {
                return false;
            }
            if (!ExportExcelInternal(ToolCmdName, "-m cs_story"))
            {
                return false;
            }
            AssetDatabase.Refresh();
            return true;
        }

        static bool ExportExcelInternal(string cmd, string arg)
        {
            string destPath = Path.GetFullPath(Path.Combine(Application.dataPath, "..", "Tables", "Tools"));

            Process p = new Process();
            p.StartInfo.FileName = Path.Combine(destPath, cmd);
            p.StartInfo.WorkingDirectory = destPath;
            p.StartInfo.Arguments = arg;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            //p.EnableRaisingEvents = true;
            //p.Exited += ProcessEnded;
            p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
            p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);

            p.Start();
            //开始异步读取输出
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();
            //调用WaitForExit会等待Exited事件完成后再继续往下执行。
            p.WaitForExit();
            int code = p.ExitCode;
            p.Close();
            if (code != 0)
            {
                EditorUtility.DisplayDialog("错误", $"打表失败，请前往控制台查看错误信息!", "ok");
                return false;
            }
            else
            {
                UnityEngine.Debug.Log($"打表成功!");
            }

            return true;
        }

        static void p_OutputDataReceived(System.Object sender, DataReceivedEventArgs e)
        {
            if (string.IsNullOrEmpty(e.Data))
            {
                return;
            }
            if (RegexErrorSign.IsMatch(e.Data))
            {
                UnityEngine.Debug.LogError(e.Data);
            }
            else
            {
                UnityEngine.Debug.Log(e.Data);
            }
        }

        static void p_ErrorDataReceived(System.Object sender, DataReceivedEventArgs e)
        {
            if (string.IsNullOrEmpty(e.Data))
            {
                return;
            }
            if (RegexErrorSign.IsMatch(e.Data))
            {
                UnityEngine.Debug.LogError(e.Data);
            }
            else
            {
                UnityEngine.Debug.Log(e.Data);
            }
        }

        /// <summary>
        /// add mac or linux chmod x
        /// </summary>
        static bool ChmodAddExecute(params string[] fullPath)
        {
            if (fullPath.Length == 0)
            {
                return true;
            }
#if UNITY_EDITOR_OSX
            Process p = new Process();
            p.StartInfo.FileName = "chmod";
            p.StartInfo.Arguments = $"+x {string.Join(" ", fullPath)}";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            //p.EnableRaisingEvents = true;
            //p.Exited += ProcessEnded;
            p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
            p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);

            p.Start();
            //开始异步读取输出
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();
            //调用WaitForExit会等待Exited事件完成后再继续往下执行。
            p.WaitForExit();
            int code = p.ExitCode;
            p.Close();
            if (code != 0)
            {
                EditorUtility.DisplayDialog("错误", $"添加mac程序执行权限失败，请前往控制台查看日志!", "ok");
                return false;
            }
            else
            {
                UnityEngine.Debug.Log($"添加mac程序执行权限成功!");
            }
#endif
            return true;
        }

        /// <summary>
        /// add mac or linux Xattr
        /// </summary>
        static bool XattrExecute(params string[] fullPath)
        {
            if (fullPath.Length == 0)
            {
                return true;
            }
#if UNITY_EDITOR_OSX

            Process p = new Process();
            p.StartInfo.FileName = "xattr";
            p.StartInfo.Arguments = $"-cr {string.Join(" ", fullPath)}";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            //p.EnableRaisingEvents = true;
            //p.Exited += ProcessEnded;
            p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
            p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);

            p.Start();
            //开始异步读取输出
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();
            //调用WaitForExit会等待Exited事件完成后再继续往下执行。
            p.WaitForExit();
            int code = p.ExitCode;
            p.Close();
            if (code != 0)
            {
                EditorUtility.DisplayDialog("错误", $"添加mac程序xattr权限失败，请前往控制台查看日志!", "ok");
                return false;
            }
            else
            {
                UnityEngine.Debug.Log($"添加mac程序xattr权限成功!");
            }
#endif
            return true;
        }

    }

}
